/**
 * @Author: lena
 * @Description:
 * @Version: 1.0.0
 * @Date: 2021/8/26 19:42
 */

package lib

import (
	"fmt"
	"reflect"
)

func Reflect(a interface{}) {
	ttt := reflect.TypeOf(a)
	fmt.Println(ttt) // 反射获取类型
	kind := ttt.Kind()
	fmt.Println(kind)
	fmt.Println(reflect.ValueOf(a)) // 反射获取值
}

func Reflect1() {
	a := "hello"
	Reflect(a) // string hello
	//	b:= study.student{sid: 1001,name:"hello"}
	//	method9(b) // study.student {1001 hello}
}

// ReflectGetValueByKey 反射获取结构体key对应value
func ReflectGetValueByKey(data interface{}, key string) string {
	if data == nil {
		return ""
	}
	return reflect.ValueOf(data).Elem().FieldByName(key).String()
}

type people struct {
	Id   int
	Name string
	Age  int
}

func (this people) Show() {
	fmt.Println(this.Id, this.Name, this.Age)
}

func ReflectMethod(p interface{}) {
	// 获取字段/方法信息
	ptype := reflect.TypeOf(p)
	// 获取值信息
	pvalue := reflect.ValueOf(p)
	// 遍历获取p的所有字段,NumField()获取字段总数
	for i := 0; i < ptype.NumField(); i++ {
		// 获取字段信息,field.Name=字段名称,field.Type=字段类型
		field := ptype.Field(i)
		// 获取字段值
		value := pvalue.Field(i).Interface()
		fmt.Println(field.Name, field.Type, value)
	}
	// 遍历获取p的所有方法,NumMethod()获取方法数量
	for i := 0; i < ptype.NumMethod(); i++ {
		// 获取方法信息,method.Name=方式名称,method.Type=方法类型
		method := ptype.Method(i)
		fmt.Println(method.Name, method.Type) // Show func(study.people)
	}
}

func Reflect2() {
	p := people{1001, "hello", 18}
	ReflectMethod(p)
}

// Reflect3 Name(),kind()：反射获取对象的数组、切片、Map、指针等类型的变量，它们的Name返回的都是空
func Reflect3() {
	p := people{Id: 1001, Name: "hello", Age: 12}
	r := reflect.TypeOf(p)
	fmt.Println(r.Name()) // people
	fmt.Println(r.Kind()) // struct
	fmt.Println("===========")
	var a = []int{1, 2, 3}
	of := reflect.TypeOf(a)
	fmt.Println(of.Name()) // (空)
	fmt.Println(of.Kind()) // slice
}

func (this *people) SetName(name string) {
	this.Name = name
}

func (this *people) SetAge(age int) {
	this.Age = age
}
